# -*- coding: utf-8 -*-
#
# File: Atividade.py
#
# Copyright (c) 2006 by IBICT
# Generator: ArchGenXML Version 1.5.0
#            http://plone.org/products/archgenxml
#
# GNU General Public License (GPL)
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA.
#

__author__ = """IBICT <cadu@ibict.br>"""
__docformat__ = 'plaintext'

from AccessControl import ClassSecurityInfo
from Products.Archetypes.atapi import *
from Products.Archetypes.SQLStorage import *
from Products.SIGFS.config import *

##code-section module-header #fill in your manual code here
from Acquisition import aq_parent, aq_inner
from email.MIMEText import MIMEText
from email.MIMEMultipart import MIMEMultipart
from email.MIMEBase import MIMEBase
from email.Message import Message
from Products.SIGFS.htmlrender import renderHTML
from Products.Archetypes import transaction
from Products.CMFCore.utils import getToolByName
##/code-section module-header

schema = Schema((

    StringField(
        name='tipo',
        index="FieldIndex",
        serchable="1",
        required=1,
        vocabulary='getTipos',
        enforceVocabulary=1,
        widget=SelectionWidget(
            label="Tipo da Atividade",
            description="Selecione o tipo em que se enquadra a Atividade.",
            format="select",
            label_msgid='SIGFS_label_tipo',
            description_msgid='SIGFS_help_tipo',
            i18n_domain='SIGFS',
        )
    ),

    DateTimeField(
        name='prazo_pendencia_atividade',
        default="DateTime()",
        serchable="1",
        required=1,
        widget=CalendarWidget(
            label="Prazo de pendência",
            description="Informe a data durante a qual os revisores poderão inserir comentários sobre a Atividade proposta, antes de publicá-la. Ela deve ser menor que a data de início da Atividade.",
            format="%d/%m/%Y",
            date_only="1",
            show_hm=False,
            label_msgid='SIGFS_label_prazo_pendencia_atividade',
            description_msgid='SIGFS_help_prazo_pendencia_atividade',
            i18n_domain='SIGFS',
        )
    ),

    BooleanField(
        name='enviar_email_atividade',
        index="FieldIndex",
        serchable="1",
        widget=BooleanWidget(
            label="Enviar email para os revisores",
            description="Selecione este campo para que quando a Atividade estiver no estado pendente seja enviado um email para os convocados presentes na Reunião revisarem a Atividade. Se este não for selecionado não será realizada esta ação de envio de email.",
            label_msgid='SIGFS_label_enviar_email_atividade',
            description_msgid='SIGFS_help_enviar_email_atividade',
            i18n_domain='SIGFS',
        )
    ),

    DateTimeField(
        name='data_inicio',
        default="DateTime()",
        widget=CalendarWidget(
            label="Data de Início",
            description="Informe a data em que a Atividade deve ser iniciada.",
            format="%d/%m/%Y",
            date_only="1",
            show_hm=False,
            label_msgid='SIGFS_label_data_inicio',
            description_msgid='SIGFS_help_data_inicio',
            i18n_domain='SIGFS',
        ),
        serchable="1",
        required=1,
        accessor="start"
    ),

    DateTimeField(
        name='data_fim',
        default="DateTime()",
        serchable="1",
        required=1,
        widget=CalendarWidget(
            label="Data estimada de término",
            description="Informe a data prevista de conclusão da Atividade.",
            format="%d/%m/%Y",
            date_only="1",
            show_hm=False,
            label_msgid='SIGFS_label_data_fim',
            description_msgid='SIGFS_help_data_fim',
            i18n_domain='SIGFS',
        )
    ),

    DateTimeField(
        name='data_conclusao',
        default="DateTime()",
        serchable="1",
        widget=CalendarWidget(
            label="Data de conclusão",
            description="Informe a data em que a Atividade foi concluída.",
            format="%d/%m/%Y",
            date_only="1",
            show_hm=False,
            label_msgid='SIGFS_label_data_conclusao',
            description_msgid='SIGFS_help_data_conclusao',
            i18n_domain='SIGFS',
        )
    ),

    TextField(
        name='descricao_atividade',
        allowable_content_types=('text/plain', 'text/structured', 'text/html', 'application/msword',),
        serchable="1",
        default_output_type='text/html',
        widget=RichWidget(
            label="Descrição da Atividade",
            description="Informe a descrição da Atividade a ser realizada.",
            label_msgid='SIGFS_label_descricao_atividade',
            description_msgid='SIGFS_help_descricao_atividade',
            i18n_domain='SIGFS',
        ),
        required=1
    ),

    LinesField(
        name='lista_convocados',
        widget=InAndOutWidget(
            label="Lista de Convocados",
            description="Selecione os convocados da Reunião que realizarão esta Atividade.",
            label_msgid='SIGFS_label_lista_convocados',
            description_msgid='SIGFS_help_lista_convocados',
            i18n_domain='SIGFS',
        ),
        serchable="1",
        multiValued=1,
        vocabulary='listConvocadosAta'
    ),

    LinesField(
        name='lista_convidados',
        widget=InAndOutWidget(
            label="Lista de Convidados e Técnicos",
            description="Selecione os técnicos e convidados da Reunião que realizarão esta Atividade.",
            label_msgid='SIGFS_label_lista_convidados',
            description_msgid='SIGFS_help_lista_convidados',
            i18n_domain='SIGFS',
        ),
        serchable="1",
        multiValued=1,
        vocabulary='listConvidadosAta'
    ),

    LinesField(
        name='outros',
        widget=InAndOutWidget(
            label="Outros",
            description="Se a Atividade em questão está relacionada a um membro que não está na lista de convidados e convocados, por favor escolha aqui. Este deve estar cadastrado no Portal.",
            label_msgid='SIGFS_label_outros',
            description_msgid='SIGFS_help_outros',
            i18n_domain='SIGFS',
        ),
        serchable="1",
        multiValued=1,
        vocabulary='getListaOutros'
    ),

),
)

##code-section after-local-schema #fill in your manual code here
##/code-section after-local-schema

Atividade_schema = BaseFolderSchema.copy() + \
    schema.copy()

##code-section after-schema #fill in your manual code here
##/code-section after-schema

class Atividade(BaseFolder):
    """
    """
    security = ClassSecurityInfo()
    __implements__ = (getattr(BaseFolder,'__implements__',()),)

    # This name appears in the 'add' box
    archetype_name = 'Atividade'

    meta_type = 'Atividade'
    portal_type = 'Atividade'
    allowed_content_types = ['TermoReferencia', 'DocumentoTecnico']
    filter_content_types = 1
    global_allow = 0
    content_icon = 'navigation_icon.gif'
    immediate_view = 'base_view'
    default_view = 'atividade_view'
    suppl_views = ()
    typeDescription = "As Atividades estão relacionadas às Resoluções e aos participantes da Reunião, mais convidados. A partir destas serão criados os Documentos Técnicos ou Termo de Referência. Quando o campo 'Enviar email para os revisores' estiver selecionado e o estado for pendente, será enviado um email aos convocados da Reunião para que possam revisar a Atividade, podendo, logo após as modificações, ser publicada. O que fará com que a Atividade seja incluída na Agenda do Escritório."
    typeDescMsgId = 'description_edit_atividade'
    allow_discussion = 1


    actions =  (


       {'action': "string:${object_url}/atividade_view",
        'category': "object",
        'id': 'view',
        'name': 'View',
        'permissions': ("View",),
        'condition': 'python:1'
       },


       {'action': 'string:${object_url}/folder_localrole_form',
        'category': "object",
        'id': 'sharing',
        'name': 'Sharing',
        'permissions': ("SIGFS: Add Atividade",),
        'condition': 'python:1'
       },


    )

    _at_rename_after_creation = True

    schema = Atividade_schema

    ##code-section class-header #fill in your manual code here
    ##/code-section class-header

    # Methods

    # Manually created methods

    def getContatos(self):
        """Retorna o Presidente, Secretário Técnico e seus dados"""
        portal_membership = getToolByName(self, 'portal_membership')
        contatos = {}
        for u in self.listConvocadosAta():
            membro = portal_membership.getMemberById(u)
            funcao = membro.getProperty('funcao', '')
            if funcao == 'Presidente':
                contatos['nome_presidente'] = membro.getProperty('fullname', '')

            elif funcao == 'Secretário Técnico':
                contatos['nome_secretario'] = membro.getProperty('fullname', '')
                contatos['email_secretario'] = membro.getProperty('email', '')
                contatos['telefone_secretario'] = membro.getProperty('telefone', '')
        return contatos

    def end(self):
        """Retorna a data inicial para aparecer marcado no calendário somente
        o dia da publicação."""
        return self.start()

    def listConvocadosAta(self):
        """Retorna a lista Convocados para a Reunião que estão no grupo
        ComiteGestor do EV em questão."""
        portal_groups = getToolByName(self, 'portal_groups')
        members = []

        for info in self.computeRoleMap():
            if info.get('type') == 'group' and 'Reviewer' in info.get('acquired'):
                group_id = info.get('id')
                group = portal_groups.getGroupById(group_id)
                members = members + [member.getId() for member in group.getGroupMembers()]

        return members

    def sendNotificationEmail(self, addresses, subject, rstText):
        """Send a notification email."""
        portal_url  = getToolByName(self, 'portal_url')
        plone_utils = getToolByName(self, 'plone_utils')

        portal      = portal_url.getPortalObject()
        mailHost    = plone_utils.getMailHost()
        charset     = plone_utils.getSiteEncoding()
        toAddresses = addresses
        fromEmail = self.getEmail()

        if toAddresses is None:
            log('Cannot send notification email: email sender addresses or name not set')
            return

        email = MIMEMultipart('alternative')
        email.epilogue = ''

        textPart = MIMEText(rstText, 'plain', charset)
        email.attach(textPart)
        htmlPart = MIMEText(renderHTML(rstText), 'html', charset)
        email.attach(htmlPart)
        message = str(email)
        mailHost.send(message = message,
                              mto = toAddresses,
                              mfrom = fromEmail,
                              subject = subject)

    security.declarePrivate('_renameAfterCreation')
    def _renameAfterCreation(self, check_auto_id=False):
        """Renomeia o objeto com id numérico sequencial de 6 casas decimais."""
	parent_ids = self.aq_inner.aq_parent.objectIds()
        try:
          new_id = 'av'+'%0.4i' % len(parent_ids)
          # Usando o portal_factory tem que comitar a subtransacao
          transaction.savepoint(optimistic=True)
	  self.setId(new_id)
	except:
	  new_id = 'av'+'%0.4i' % len(parent_ids) + str(random.randint(1,1000))
          # Usando o portal_factory tem que comitar a subtransacao
          transaction.savepoint(optimistic=True)
	  self.setId(new_id)

    def listConvidadosAta(self):
        """Retorna a lista Convidados em geral."""
        portal_membership = getToolByName(self, 'portal_membership')
        convocados = self.listConvocadosAta()

        return [i for i in portal_membership.listMemberIds() if i not in convocados]

    def getEmail(self):
        """Get the default email address, that of the creating user"""
        portal_groups = getToolByName(self, 'portal_groups')
        members = []

        for info in self.computeRoleMap():
            if info.get('type') == 'group' and 'Member' in info.get('acquired'):
                group_id = info.get('id')
                group = portal_groups.getGroupById(group_id)
                return group.getProperty('email',)

    def getTipos(self):
        """Retorna a lista de Tipos de Atividades."""
        portal_sigfs = getToolByName(self, 'portal_sigfs')
        result = []
        vocabulary = portal_sigfs.getVocab_tipo()

        for item in vocabulary:
            parts = item.split(';')
            result.append([parts[0], parts[1]])
        return DisplayList(tuple(result))

    def getFundoSetorial(self):
        """Retorna o Fundo Setorial que está enviando o email"""
        resolucao = self.aq_inner.aq_parent
        obj = resolucao.aq_inner.aq_parent
        if obj.portal_type == 'EscritorioVirtualComite':
            fundo = obj.aq_inner.aq_parent
            return fundo.Title()
        else:
            reuniao = obj.aq_inner.aq_parent
            ev = reuniao.aq_inner.aq_parent
            fundo = ev.aq_inner.aq_parent
            return fundo.Title()

    def sendNotificationMail(self):
        """Quando a atividade é publicada, envia uma notificação
        por email para os responsáveis pela atividade."""
        portal_membership = getToolByName(self, 'portal_membership')
        usuarios = self.getLista_convocados() + self.getLista_convidados() + self.getOutros()
        contatos = self.getContatos()
        fundo = self.getFundoSetorial()

        subject = "Convocação para atividade"
        mailText = self.atividade_send_mail(self, atividade=self, contatos=contatos, fundo=fundo)

        for u in usuarios:
            email = portal_membership.getMemberById(u).getProperty('email', '')
            if email: self.sendNotificationEmail(email, subject, mailText)

    def getListaOutros(self):
        """Retorna uma lista com todos os membros"""
        try:
            ata = self.aq_inner.aq_parent
            outros = ata.listConvidados()
            return outros
        except:
            portal_membership = getToolByName(self, 'portal_membership')
            return portal_membership.listMemberIds()



registerType(Atividade, PROJECTNAME)
# end of class Atividade

##code-section module-footer #fill in your manual code here
##/code-section module-footer



